﻿using UnityEngine;
using UnityEngine.UI;

namespace Miao.UI
{
    /// <summary>
    /// 带最大尺寸约束的ContentSizeFitter
    /// 可以用于动态Text，并在特定长度后换行。
    /// </summary>
    public class ConstrainedContentSizeFitter : ContentSizeFitter
    {
        [Header("尺寸约束")]
        [SerializeField] private float maxWidth = 300f;
        [SerializeField] private float maxHeight = -1f; // -1表示不限制高度
        [SerializeField] private bool enableWidthConstraint = true;
        [SerializeField] private bool enableHeightConstraint = false;

        [System.NonSerialized] private RectTransform m_Rect;
        private RectTransform rectTransform
        {
            get
            {
                if (m_Rect == null)
                    m_Rect = GetComponent<RectTransform>();
                return m_Rect;
            }
        }
        protected override void Awake()
        {
            base.Awake();
        }

        public override void SetLayoutHorizontal()
        {
            HandleHorizontalLayout();
        }

        public override void SetLayoutVertical()
        {
            HandleVerticalLayout();
        }

        private void HandleHorizontalLayout()
        {
            if (horizontalFit == FitMode.Unconstrained)
                return;

            if (horizontalFit == FitMode.MinSize)
            {
                rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal,
                    GetConstrainedSize(LayoutUtility.GetMinSize(rectTransform, 0), true));
            }
            else if (horizontalFit == FitMode.PreferredSize)
            {
                float preferredWidth = LayoutUtility.GetPreferredSize(rectTransform, 0);
                rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal,
                    GetConstrainedSize(preferredWidth, true));
            }
        }

        private void HandleVerticalLayout()
        {
            if (verticalFit == FitMode.Unconstrained)
                return;

            if (verticalFit == FitMode.MinSize)
            {
                rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical,
                    GetConstrainedSize(LayoutUtility.GetMinSize(rectTransform, 1), false));
            }
            else if (verticalFit == FitMode.PreferredSize)
            {
                float preferredHeight = LayoutUtility.GetPreferredSize(rectTransform, 1);
                rectTransform.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical,
                    GetConstrainedSize(preferredHeight, false));
            }
        }

        private float GetConstrainedSize(float originalSize, bool isWidth)
        {
            if (isWidth && enableWidthConstraint && maxWidth > 0)
            {
                return Mathf.Min(originalSize, maxWidth);
            }
            else if (!isWidth && enableHeightConstraint && maxHeight > 0)
            {
                return Mathf.Min(originalSize, maxHeight);
            }

            return originalSize;
        }

        // 公共接口
        public void SetMaxWidth(float newMaxWidth)
        {
            maxWidth = newMaxWidth;
            SetDirty();
        }

        public void SetMaxHeight(float newMaxHeight)
        {
            maxHeight = newMaxHeight;
            SetDirty();
        }

        public float GetMaxWidth() => maxWidth;
        public float GetMaxHeight() => maxHeight;
    }
}